<script>
/**
 * @Author: 焦质晔
 * @Date: 2019-06-20 10:00:00
 * @Last Modified by: mikey.zhaopeng
 * @Last Modified time: 2019-12-17 11:12:14
 **/
import axios, { getConfigHeaders } from '@/api/fetch';
import moment from 'moment';
import { findFileByUrl } from '@/api/partsmanage/financialManagement/capitalAccount/index';
import config from '@/assets/js/config';
import ElImageViewer from 'element-ui/packages/image/src/image-viewer';
export default {
  name: 'UploadFile',
  props: {
    actionUrl: {
      type: String,
      required: true
    },
    initialValue: {
      type: Array,
      default: () => []
    },
    fileTypes: {
      type: Array,
      default: () => ['jpg', 'png', 'pdf', 'xls', 'xlsx', 'docx', 'doc', 'zip', 'rar']
    },
    isOnlyButton: {
      type: Boolean,
      default: false
    },
    limit: {
      type: Number,
      default: 1
    },
    fileSize: {
      type: Number,
      default: 20
    },
    params: {
      type: Object,
      default: () => ({})
    },
    disabled: {
      type: Boolean,
      default: false
    },
    autoUpload: {
      type: Boolean,
      default: true
    },
    containerStyle: {
      type: Object,
      default: () => ({})
    },
    autoUploadDisplay: {
      type: Boolean,
      default: true
    },
    extra: {
      type: Object,
      default: () => ({})
    },
    fileRatio: {
      type: Array,
      default: () => []
    },
  },
  components: { ElImageViewer },
  data() {
    return {
      fileList: this.initialValue,
      currentBucketType: '',
      picUrl: [],
      imagesViewShow: false,
      uploadUrl: `${config.uploadUrl}/api/file/v1/file/upload`,
      beforeUploadError: false
    };
  },
  watch: {
    initialValue(val) {
      this.fileList = this.initialValue;
    },
    fileList(val) {
      if (!this.beforeUploadError) return;
      this.$emit('change', val);
    }
  },
  methods: {
    async beforeUploadHandle(file) {
      //cms 添加， 为了增加loading等待
      // this.$emit('change', 1);
      const fileFormat = file.name.slice(file.name.lastIndexOf('.') + 1).toLowerCase();
      const isType = this.fileTypes.includes(fileFormat);
      const isExtraType = !_.isEmpty(this.extra) && this.extra.fileTypes.includes(fileFormat);
      const isLt5M = file.size / 1024 / 1024 < this.fileSize;
      let isSizeMatch = true;

      if (!isType && !isExtraType) {
        this.$notify({ title: '提示信息', message: `上传的文件只能是 ${this.fileTypes.join(',')} 格式！`, type: 'warning' });
      }else if (!isLt5M && isType && !isExtraType) {
        this.$notify({ title: '提示信息', message: `上传文件大小不能超过 ${this.fileSize}M！`, type: 'warning' });
      }else{
        isSizeMatch = await this.checkFileSizeMatch(file, this.fileRatio);
      }

      let isLimitExtraSize = false;
      if (isExtraType) {
        isLimitExtraSize = file.size / 1024 / 1024 < this.extra.fileSize;
        !isLimitExtraSize && this.$notify({ title: '提示信息', message: `${this.extra.fileTypes.join(',')} 文件大小不能超过 ${this.extra.fileSize}M！`, type: 'warning' });
      }
      this.beforeUploadError = isType && (isLt5M || isLimitExtraSize) && isSizeMatch;
      console.log("this.beforeUploadError:",this.beforeUploadError);
      return isType && (isLt5M || isLimitExtraSize) && isSizeMatch;
    },

    async checkFileSizeMatch(file, fileRatio){
      let isSizeMatch = true;
      if(fileRatio.length > 0){
        const imgParam = fileRatio;
        const widthPercent = imgParam[0];
        const heightPercent = imgParam[1];
        const widthMin = imgParam[2];
        return new Promise((resolve, reject) => {
          let reader = new FileReader()
          reader.readAsDataURL(file) // 必须用file.raw
          reader.onload = () => {
            // 让页面中的img标签的src指向读取的路径
            let img = new Image()
            img.src = reader.result

            img.onload = () => {
              if(img.width < widthMin){
                isSizeMatch = false;
                this.$notify({ title: '提示信息', message: `需上传图片宽度大于${widthMin},当前文件${img.width},文件上传失败!`, type: 'error' });
                resolve(isSizeMatch);
                return;
              }
              if (img.width / img.height !== widthPercent/heightPercent) {
                isSizeMatch = false;
                this.$notify({ title: '提示信息', message: `需上传图片宽高比例为${widthPercent}:${heightPercent},当前文件${img.width}×${img.height},文件上传失败!`, type: 'error' });
                resolve(isSizeMatch);
                return;
              }
              resolve(isSizeMatch);
            }
          }
        });
      }else{
        return isSizeMatch;
      }
    },

    removeFileHandle(file, fileList) {
      if (this.fileList.length != fileList.length) {
        this.fileList = fileList;
        this.$emit('change', this.fileList);
      }

    },
    successHandle(res, file, fileList) {
      if (res.resultCode === 200 || res.returnCode === '0') {
        this.fileList = this.$props.multiple ? [...this.fileList, { name: file, url: res.data.url || '' }] : [...this.fileList, { name: file, url: res.data.url || '' }];
        this.$emit('success', this.fileList);
      } else {
        this.errorHandle(res.errMsg);
      }
    },
    errorHandle(err) {
      this.$emit('error', err || '');
      this.$message.error(err || '文件上传失败！');
    },
    previewFileHandle(file) {
      if (this.currentBucketType === 'pubilc') return;
      const fileFormat = file.url.slice(file.url.lastIndexOf('.') + 1).toLowerCase();
      const imgFormat = ['jpeg', 'jpg', 'png', 'gif', 'bmp'];
      //console.log('fileFormat imgFormat', file, fileFormat, imgFormat.includes(fileFormat))
      this.downloadFile(file, imgFormat.includes(fileFormat));

    },
    // 获取服务端文件 to blob
    async downLoadByUrl(url, params = {}) {
      // url = url.replace(/\%/g, "%25");
      // url = url.replace(/\+/g, "%2B");
      // url = url.replace(/\&/g, "%26");
      // url = url.replace(/\?/g, "%3F");
      // url = url.replace(/\#/g, "%23");
      // url = url.replace(/\=/g, "%3D");
      url = encodeURIComponent(url);
      //console.log('url', url);
      let res = await findFileByUrl(url);
      if (res.resultCode === 200) {
        return res.data;
      } else {
        this.$message.error('文件下载失败！');
      }

    },
    // 执行下载动作
    async downloadFile({ url, name }, params) {
      let data;

      if (this.params.hasOwnProperty('bucketType')) {
        this.currentBuketType = this.params.bucketType;
      }
      if (this.currentBuketType === 'public') {
        data = url;
      } else {
        data = await this.downLoadByUrl(url);
      }

      if (params) {
        this.picUrl = [data];
        this.imagesViewShow = true;
      } else {
        let a = document.createElement('a');
        a.href = data;
        a.target = '_blank';
        a.click();
        a = null;
      }
    },
    submitUpload() {
      this.$refs.upload.submit();
    },
    httpRequest(param) {
      if (!this.beforeUploadError) return;
      let file = param.file;
      let { fileName, bucketType = 'private' } = param.data;
      let fileType = param.file.name.split('.')[1];
      this.currentBucketType = bucketType;
      if (fileName) {
        fileName = `${fileName}-${moment().format('YYYY-MM-DD')}-${new Date().getTime()}${Math.random().toString().split('.')[1].substring(0, 10)}.${fileType}`;
      } else {
        fileName = `${param.file.name.substring(0, param.file.name.lastIndexOf("."))}-${moment().format('YYYY-MM-DD HH:mm:ss')}`;
      }
      let form = new FormData();
      form.append('file', file);
      form.append('bucketType', bucketType);
      form.append('fileName', fileName);
      const { $props } = this;
      if ($props.actionUrl) {
        if (!$props.actionUrl.includes('/api/file/oss/upload')) {
          this.uploadUrl = $props.actionUrl;
        }
      }
      console.log(getConfigHeaders())
      axios({
        method: 'post',
        url: this.uploadUrl,
        data: form,
        headers: getConfigHeaders(this.uploadUrl),
        onUploadProgress: progressEvent => {
          const complete = parseInt(((progressEvent.loaded / progressEvent.total) * 100) | 0, 10)
          // 重点二：onProgress()方法需要以上方接收的形参来调用
          // 这个方法有一个参数"percent"，给他进度值 complete 即可
          param.onProgress({ percent: complete })
        }
      }).then(res => {
        this.successHandle(res, fileName);
      });

      // axios.post(uploadUrl, form).then(res => {
      //   this.successHandle(res, fileName);
      // });
    },
    handleExceed() {
      this.$message.warning(`每次只能上传${this.limit}个文件`);
    },
    closeImagesViewer() {
      this.imagesViewShow = false;
    }
  },

  render() {
    const { $props, $attrs, $slots, $listeners, fileList, fileTypes, fileSize, containerStyle, picUrl, imagesViewShow, fileRatio } = this;
    this.currentBucketType = $props.params.hasOwnProperty('bucketType') ? $props.params.bucketType : 'private';
    const wrapProps = {
      props: {
        action: $props.actionUrl,
        headers: getConfigHeaders(this.uploadUrl),
        data: $props.params,
        fileList,
        limit: $props.limit,
        showFileList: !$props.isOnlyButton,
        multiple: $props.limit > 1,
        withCredentials: true,
        disabled: $props.disabled,
        onPreview: this.previewFileHandle,
        beforeUpload: this.beforeUploadHandle,
        onRemove: this.removeFileHandle,
        onSuccess: this.successHandle,
        onError: this.errorHandle,
        autoUpload: $props.autoUpload,
        autoUploadDisplay: $props.autoUploadDisplay,
        httpRequest: this.httpRequest,
        onExceed: this.handleExceed
      },
      multiple: $props.limit > 1,
      on: $listeners
    };
    const btnProps = {
      attrs: {
        type: 'primary',
        disabled: $props.disabled,
        ...$attrs
      }
    };
    const imagesViewerProps = {
      props: {
        onClose: this.closeImagesViewer
      }
    };
    return (
      <div class="upload-btn" style={containerStyle}>
        <el-upload ref="upload" {...wrapProps}>
          <el-button slot="trigger" {...btnProps}>
            {$slots['default']}
          </el-button>
          {!$props.autoUpload && $props.autoUploadDisplay && (
            <el-button style="margin-left: 10px;" size="small" type="primary" disabled={$props.disabled} onClick={this.submitUpload}>
              上传到服务器
            </el-button>
          )}
          {!$props.isOnlyButton ? ($props.disabled ? (<div slot="tip" class="el-upload__tip">{`附件详细，支持查看和下载`}</div>) :
            (<div slot="tip" class="el-upload__tip">{`只能上传 ${fileTypes.join(',')} 格式，文件大小不超过${fileSize}M`}<p>{_.isEmpty($props.extra) ? '' : `${$props.extra.fileTypes.join(',')} 格式，文件大小不超过${$props.extra.fileSize}M`}</p></div>)
          ) : null}
          { fileRatio.length < 3 ? null :(<div slot="tip" class="el-upload__tip">{`只能上传宽高比例为${fileRatio[0]}:${fileRatio[1]},宽度不低于${fileRatio[2]}px的图片`}</div>)}
        </el-upload>
        <el-image-viewer urlList={picUrl} v-show={imagesViewShow} {...imagesViewerProps}></el-image-viewer>
      </div>
    );
  }
};
</script>

<style lang="less" scoped>
.upload-btn {
  display: inline-block;
}
</style>
